open Printf
open Ext

exception Error

module Array =
struct
	include Array


	let trans a = 
		let m = Array.length a in
		let n = Array.length a.(0) in
  		for i = 1 to m-1 do 
			if Array.length a.(i) <> n then raise Error 
		done;
   		Array.init n (fun i -> Array.init m (fun j -> a.(j).(i)))

	let take a indexes =
		(*Array.iter (printf "%d ") indexes;
		printf "\n"; *)
		let n = Array.length indexes in

		let newAr = if n > 0 then Array.make n a.(0) else [||] in

		flush_all();
		for i=0 to n - 1 do
			(*printf "i:%d indexes.(i):%d len_a:%d\n" i (indexes.(i)) (Array.length a); 
			*)
			flush_all();
			newAr.(i) <- a.(indexes.(i))
		
		done;

		flush_all();
		newAr
	
	let takeCol matrix indexes =
		let matrix' = trans matrix in
		let augemented = Array.mapi (fun i row->(row, i)) matrix' in
		let result = take augemented indexes in
		let reg = Array.map (fst) result in
		let reg' = trans reg in

		reg'

	let takeRow matrix indexes =
		let augemented = Array.mapi (fun i row->(row, i)) matrix in
		let result = take augemented indexes in
		let reg = Array.map (fst) result in
		reg

	
	let range n = 
		let ar = Array.make n 0 in
		for i = 0 to n - 1 do
			ar.(i) <- i
		done;
		ar

	let subtract a b =

		let y = ref [] in
		for i = (Array.length a) downto 0 do
			if (Array.find (fun x-> x == a.(i)) b ) then 
				ignore()
			else
				y := a.(i) :: !y
		done;
		Array.of_list !y


	let ipartition i a = 
		
    let y = ref [] and n = ref [] in
    for j = Array.length a - 1 downto 0 do 
      if j < i then
        y := a.(j) :: !y
      else
        n := a.(j) :: !n
    done;
    (Array.of_list !y, Array.of_list !n)
	
	let augment a =
		Array.mapi ( fun i x-> (x,i) ) a  


	
	let normalizelog a =
		let logsum = alogsumexp a in (*Array.sumf (Array.map (exp) a) in *)
		let n_a = Array.map (fun x->  x  -. logsum) a in
		n_a

end 

module List = 
struct
	include List


	let rem_first l = 
  		match l with            
    		| [] -> []
		| h::t -> t 

	let rem_item l item = 
		let newl = ref [] in
		let la = Array.of_list l in
 		for i = (List.length l) - 1 downto 0 do 
		if la.(i) <> item then newl := la.(i)::!newl
		done;
		!newl

end

